package edu.ubb.remeye.server.settings;

import java.util.ArrayList;
import java.util.List;

import org.codecompany.jeha.ExceptionHandler;
import org.codecompany.jeha.core.HandlerUtil;

import edu.ubb.remeye.encodings.EncodingType;
import edu.ubb.remeye.exception.SettingsLoadingException;
import edu.ubb.remeye.exception.SettingsSavingException;
import edu.ubb.remeye.exception.handler.RemEyeExceptionHandler;
import edu.ubb.remeye.security.SecurityType;
import edu.ubb.remeye.server.settings.jaxb.ServerSettings;
import edu.ubb.remeye.util.jaxb.JAXBBinder;

/**
* Server settings manager class.
* 
* @author Andrew Ianicicau
*
*/
@ExceptionHandler(handler=RemEyeExceptionHandler.class)
public class ServerSetter {

	///////////////////////////////////////////////////////////////////////////////////
	////		ATTRIBUTES - ServerSetter
	///////////////////////////////////////////////////////////////////////////////////

	/**
	 * Private attribute of this class for singleton design pattern.
	 */
	private static ServerSetter serverSetter;
	
	/**
	 * JAXB object, settings are stored in it.
	 */
	private static ServerSettings settings;

	
	
	///////////////////////////////////////////////////////////////////////////////////
	////		CONSTRUCTORS - ServerSetter
	///////////////////////////////////////////////////////////////////////////////////

	private ServerSetter() {
		try {
			settings = (ServerSettings) JAXBBinder.loadSettings(true);
		} catch(SettingsLoadingException e) {
			HandlerUtil.handle(e);
		} 
		
		if(settings == null) {
			settings = new ServerSettings();
			settings.setPort(5900);
			for(SecurityType type : SecurityType.getSecurityTypeList())
				settings.getAvailableSecurity().add(type.ordinal());
			for(EncodingType type : EncodingType.getEncodingTypeList())
				settings.getAvailableEncoding().add(type.ordinal());
			saveSettings();
		}
	}
	
	
	
	///////////////////////////////////////////////////////////////////////////////////
	////		METHODS
	///////////////////////////////////////////////////////////////////////////////////
	
	/**
	 * Singleton design pattern instance provider method.
	 */
	public static ServerSetter getInstance() {
		if(serverSetter == null)
			serverSetter = new ServerSetter();
		return serverSetter;
	}
	
	public int getPort() {
		return settings.getPort();
	}
	
	public void setPort(int port) {
		if(port > 1024 && port <= 65535) {
			settings.setPort(port);
		}
	}
	
	public List<SecurityType> getSecurityTypes() {
		List<Integer> security = settings.getAvailableSecurity();
		List<SecurityType> securityTypes = new ArrayList<SecurityType>();
		for(Integer ordinal : security)
			securityTypes.add(SecurityType.getSecurityType(ordinal));
		return securityTypes;
	}
	
	public void setSecurityTypes(List<SecurityType> securityTypes) {
		settings.getAvailableSecurity().clear();
		for(SecurityType type : securityTypes) {
			if(!settings.getAvailableSecurity().contains(type.ordinal()))
				settings.getAvailableSecurity().add(type.ordinal());
		}
	}
	
	public List<EncodingType> getEncodingTypes() {
		List<Integer> encoding = settings.getAvailableEncoding();
		List<EncodingType> encodingTypes = new ArrayList<EncodingType>();
		for(Integer ordinal : encoding)
			encodingTypes.add(EncodingType.getEncodingType(ordinal));
		return encodingTypes;
	}
	
	public void setEncodingTypes(List<EncodingType> encodingTypes) {
		settings.getAvailableEncoding().clear();
		for(EncodingType type : encodingTypes) {
			if(!settings.getAvailableEncoding().contains(type.ordinal()))
				settings.getAvailableEncoding().add(type.ordinal());
		}
	}
	
	public void saveSettings() {
		try {
			JAXBBinder.saveSettings(settings, true);
		} catch(SettingsSavingException e) {
			HandlerUtil.handle(e);
		}
	}

}
